/**
 * 数字滚动动画组件
 * 用于显示数据变化时的平滑过渡效果
 */

"use client"

import { useEffect, useRef, useState } from "react"

interface AnimatedNumberProps {
  value: number
  decimals?: number
  duration?: number
  prefix?: string
  suffix?: string
  className?: string
  formatter?: (value: number) => string
}

export function AnimatedNumber({
  value,
  decimals = 0,
  duration = 800,
  prefix = '',
  suffix = '',
  className = '',
  formatter,
}: AnimatedNumberProps) {
  const [displayValue, setDisplayValue] = useState(value)
  const previousValueRef = useRef(value)
  const animationFrameRef = useRef<number>()

  useEffect(() => {
    const startValue = previousValueRef.current
    const endValue = value
    const startTime = performance.now()

    const animate = (currentTime: number) => {
      const elapsed = currentTime - startTime
      const progress = Math.min(elapsed / duration, 1)

      // 使用 easeOutExpo 缓动函数
      const eased = progress === 1 ? 1 : 1 - Math.pow(2, -10 * progress)
      const current = startValue + (endValue - startValue) * eased

      setDisplayValue(current)

      if (progress < 1) {
        animationFrameRef.current = requestAnimationFrame(animate)
      } else {
        previousValueRef.current = endValue
      }
    }

    // 只有当值真正变化时才动画
    if (startValue !== endValue) {
      animationFrameRef.current = requestAnimationFrame(animate)
    }

    return () => {
      if (animationFrameRef.current) {
        cancelAnimationFrame(animationFrameRef.current)
      }
    }
  }, [value, duration])

  const formattedValue = formatter
    ? formatter(displayValue)
    : displayValue.toFixed(decimals)

  return (
    <span className={className}>
      {prefix}{formattedValue}{suffix}
    </span>
  )
}

/**
 * 百分比动画组件（带颜色变化）
 */
interface AnimatedPercentProps {
  value: number
  decimals?: number
  duration?: number
  showSign?: boolean
  className?: string
}

export function AnimatedPercent({
  value,
  decimals = 2,
  duration = 800,
  showSign = true,
  className = '',
}: AnimatedPercentProps) {
  const colorClass = value >= 0 ? 'text-success' : 'text-destructive'

  return (
    <AnimatedNumber
      value={value}
      decimals={decimals}
      duration={duration}
      prefix={showSign && value > 0 ? '+' : ''}
      suffix="%"
      className={`transition-colors duration-300 ${colorClass} ${className}`}
    />
  )
}

/**
 * 金额动画组件（带千分位分隔符）
 */
interface AnimatedCurrencyProps {
  value: number
  decimals?: number
  duration?: number
  symbol?: string
  className?: string
}

export function AnimatedCurrency({
  value,
  decimals = 2,
  duration = 800,
  symbol = '¥',
  className = '',
}: AnimatedCurrencyProps) {
  return (
    <AnimatedNumber
      value={value}
      decimals={decimals}
      duration={duration}
      prefix={symbol}
      className={className}
      formatter={(val) => val.toLocaleString('zh-CN', {
        minimumFractionDigits: decimals,
        maximumFractionDigits: decimals,
      })}
    />
  )
}


